home *** CD-ROM | disk | FTP | other *** search
/ Just Call Me Internet / Just Call Me Internet.iso / prog / atari / m2 / cat3src / magic / i / mintutil.i < prev    next >
Text File  |  1997-10-26  |  7KB  |  238 lines

  1. IMPLEMENTATION MODULE MintUtil;
  2.  
  3. FROM SYSTEM IMPORT ADR, BYTE, WORD, LONGWORD, ADDRESS, CAST;
  4. (*$R-,S-*)
  5.  
  6. IMPORT MagicDOS, Mintbind, MagicCookie, MagicStrings, StrConv;
  7. IMPORT MagicSys;
  8.  
  9. (* Mehrere kleinere MiNT Tricks. Version 2   Karsten Isakovic / Berlin
  10.  *
  11.  * - Umlenken der Ausgaben eines paralellen Prozesses nach /dev/null
  12.  * - Umlenken der Ausgaben eines paralellen Prozesses in eine Pipe
  13.  * - Auslesen der Ausgaben aus der Pipe.
  14.  *)
  15.  
  16. (* Version in Megamax Modula 2 von Dirk Steins unter Benutzung 
  17.  * von Magic von Peter Hellinger
  18.  *)
  19.  
  20. TYPE voidType = RECORD
  21.                   CASE :CARDINAL OF
  22.                     1 : b : BYTE|
  23.                     2 : w : WORD|
  24.                     3 : l : LONGWORD|
  25.                     4 : card : CARDINAL|
  26.                     5 : int  : INTEGER|
  27.                     6 : lcard: LONGCARD|
  28.                     7 : lint : LONGINT|
  29.                     8 : char : CHAR|
  30.                     9 : bset : BITSET|
  31.                     10: lbset: MagicSys.lBITSET |
  32.                     11: bool : BOOLEAN; |
  33.                     12: r    : ARRAY [0..3] OF INTEGER|
  34.                     13: a    : ADDRESS;
  35.                   END
  36.                 END;
  37.  
  38. VAR v : voidType;
  39.  
  40.  
  41. (*
  42.  * Startet einen paralellen Prozess der nach /dev/null ausgibt.
  43.  * Liefert den PID des neuen Prozesses.
  44.  *)
  45.  
  46. (*$W-*) 
  47. PROCEDURE ExecDevNull(REF name, cmdline, env : ARRAY OF CHAR): INTEGER;
  48. VAR   null, i, pid : INTEGER;
  49.       old          : ARRAY [0..3] OF INTEGER;
  50. BEGIN
  51.   FOR i:=0 TO 3 DO
  52.     old[i] := MagicDOS.Fdup(i-1);   (* Kan„le -1 .. 2 duplizieren *)
  53.   END(*FOR*);
  54.  
  55.   null := MagicDOS.Fopen("u:\dev\null",{MagicDOS.ReadWrite});
  56.   FOR i:= 0 TO 3 DO
  57.     v.bool := MagicDOS.Fforce(i-1,null);     (* Kan„le -1 .. 2auf /dev/null *)
  58.   END(*FOR*);
  59.  
  60.   pid := Mintbind.Pfork();     (* Prozess verdoppeln          *)
  61.  
  62.   IF (pid = 0) 
  63.   THEN                           (* Der neue Kindprozess...     *)
  64.     FOR i:=0 TO 3 DO
  65.       v.int := MagicDOS.Fclose(old[i]);     (* Kopien schliežen            *)
  66.     END(*FOR*);
  67.  
  68.     v.int := MagicDOS.Pexec(200, name, cmdline, env);  (* šberlagern       *)
  69.     MagicDOS.Pterm(-1);            (* Kommt hier nur an, wenn     *)
  70.                                    (* Pexec nicht klappte         *)
  71.   END(*IF*);
  72.  
  73.   FOR i:= 0 TO 3 DO
  74.     v.bool := MagicDOS.Fforce(i-1,old[i]);   (* Kan„le -1 .. 2 zurcksetzen *)
  75.     v.int := MagicDOS.Fclose(old[i]);       (* Kopien schliežen            *)
  76.   END(*FOR*);
  77.  
  78.   v.int := MagicDOS.Fclose(null);
  79.  
  80.   RETURN pid;
  81. END ExecDevNull;
  82.  
  83.  
  84. (*
  85.  * Startet einen parallelen Prozess der in eine neue Pipe ausgibt.
  86.  * Liefert den PID des neuen Prozesses und den Filehandle
  87.  * der Pipe in 'pipe'.
  88.  *)
  89.  
  90. PROCEDURE ExecPipe (REF name, cmdline, env : ARRAY OF CHAR; VAR pipe : INTEGER) : INTEGER;
  91.   VAR pipename     : ARRAY [0..39] OF CHAR;
  92.       old          : ARRAY [0..3] OF INTEGER;
  93.       i, masterfd, 
  94.       slavefd, pid : INTEGER;
  95.       
  96. BEGIN
  97.   pipe := -1;
  98.   
  99.   i := 0;
  100.   LOOP
  101.     IF i > 999 THEN EXIT END;
  102.     MagicStrings.Assign ('u:\pipe\pty.',pipename);
  103.     MagicStrings.Append (StrConv.NumToStr (i,10,3,'0'), pipename);
  104.     masterfd := MagicDOS.Fcreate (pipename, {MagicSys.Bit2});
  105.     IF masterfd > 0 THEN EXIT END;
  106.     INC (i);
  107.   END;
  108.   
  109.   IF masterfd < 0 THEN RETURN -1 END;
  110.  
  111.   slavefd := MagicDOS.Fopen (pipename, {MagicDOS.ReadWrite});
  112.   IF slavefd < 0 
  113.   THEN
  114.     v.int := MagicDOS.Fclose (masterfd);
  115.     RETURN -1
  116.   END;
  117.  
  118.  
  119.   FOR i := 0 TO 3 DO 
  120.     old[i] := MagicDOS.Fdup (i-1); (* Kan„le -1..2 duplizieren *)
  121.   END;
  122.  
  123.   FOR i := 0 TO 3 DO
  124.     v.bool := MagicDOS.Fforce(i-1,slavefd);  (* Kan„le -1 .. 2 umsetzen     *)
  125.   END;
  126.  
  127.   pid := Mintbind.Pfork();     (* Prozess verdoppeln          *)
  128.  
  129.   IF (pid = 0) THEN           (* Der neue Kindprozess...     *)
  130.     FOR i := 0 TO 3 DO 
  131.       v.int := MagicDOS.Fclose(old[i]);     (* Kopien schliežen            *)
  132.     END;
  133.  
  134.     v.int := MagicDOS.Pexec(200, name, cmdline, env);  (* šberlagern       *)
  135.     MagicDOS.Pterm(-1);            (* Kommt hier nur an, wenn     *)
  136.                           (* Pexec nicht klappte         *)
  137.   END; (* IF *)
  138.  
  139.   FOR i := 0 TO 3 DO
  140.     v.bool := MagicDOS.Fforce(i-1,old[i]);   (* Kan„le -1 .. 2 zurcksetzen *)
  141.     v.int := MagicDOS.Fclose(old[i]);       (* Kopien schliežen            *)
  142.   END;
  143.   v.int := MagicDOS.Fclose(slavefd);
  144.  
  145.   pipe := masterfd;
  146.   RETURN pid;
  147. END ExecPipe;
  148.  
  149.  
  150. (*
  151.  * Liest von einer Pipe, sofern dort Daten vorhanden sind.
  152.  * Liefert Null, wenn keine Daten da waren, -1 wenn der
  153.  * Pipe-Prozess bendet wurde und einen positiven Wert, wenn
  154.  * Zeichen gelesen wurden.
  155.  *)
  156.  
  157. VAR   rus   : ARRAY [0..7] OF LONGINT;
  158.  
  159. PROCEDURE ReadPipe (pid, pipe : INTEGER; VAR buf : ARRAY OF CHAR;
  160.                     VAR retCode : INTEGER): LONGINT;
  161.   VAR size : LONGINT;
  162.       cSize : LONGCARD;
  163.       lc    : MagicSys.lBITSET;
  164. BEGIN
  165.  
  166.   size := Mintbind.Finstat (pipe);
  167.   IF  (size > 0) THEN
  168.     IF size > LONGINT(LONG(HIGH (buf))) THEN
  169.       size := HIGH(buf);
  170.     END;
  171.     cSize := size;
  172.     MagicDOS.Fread(pipe,cSize,ADR(buf));
  173.     size := cSize;
  174.   END;
  175.  
  176.   IF  (size <= 0)          (* Testen ob Prozess gestorben ist *)
  177.       & (Mintbind.Pkill(pid,0) < 0)
  178.   THEN
  179.     lc := MagicSys.lBITSET{};
  180.     v.int := Mintbind.Fselect(150, lc, lc, NIL);  (* Meist kommt trotzdem noch etwas  *)
  181.                                      (* in der Pipe an, also kurz warten *)
  182.     IF Mintbind.Finstat(pipe) = 0
  183.     THEN
  184.       v.int := MagicDOS.Fclose(pipe); (* Pipe schliežen, wenn nichts kam  *)
  185.     END;
  186.  
  187.     v.lint := Mintbind.Pwait3(1,rus);           (* Zombie entfernen *)
  188.     IF v.lint # LONG(MagicDOS.EFilNF)
  189.     THEN
  190.       retCode := CAST (INTEGER, v.lint);        (* Einfach abschneiden *)
  191.     ELSE
  192.       retCode := 0;
  193.     END;
  194.   END;
  195.   RETURN size;
  196. END ReadPipe;
  197.  
  198.  
  199. (*
  200.  * Liefert 1 wenn MiNT installiert ist, sonst 0.
  201.  *)
  202.  
  203. PROCEDURE IsMiNT() : BOOLEAN;
  204.   VAR val : LONGCARD;
  205. BEGIN
  206.   RETURN MagicCookie.FindCookie ('MiNT', val)
  207. END IsMiNT;
  208.  
  209. (*
  210. VAR pipe, pid : INTEGER;
  211.     str       : ARRAY [0..152] OF CHAR;
  212.     size      : LONGINT;
  213. BEGIN
  214.  
  215.   IF ~IsMiNT() THEN
  216.     WriteString ("Leider kein MiNT installiert...");
  217.     WriteLn;
  218.     RETURN 
  219.   END;
  220.  
  221.   v.int := ExecDevNull ("c:\usr\mint\ls.ttp","","");
  222.  
  223.   pid := ExecPipe ("c:\usr\mint\ps.ttp",2c+"-l","",pipe);
  224.   IF pid > 0 
  225.   THEN
  226.     REPEAT
  227.       size := ReadPipe (pid, pipe, str);
  228.       IF size > 0 THEN
  229.         str[SHORT(size)] := 0c;
  230.         WriteString (str);
  231.       END;
  232.     UNTIL size < 0;
  233.   END;
  234.  
  235.   v.lint:=Mintbind.Pwait3(0,rus);           (* Warten bis Kind (/dev/null) beendet *)
  236. *)
  237. END MintUtil.
  238.